讓電腦看得懂人類語言的第一步 - 詞向量


在介紹各種不明覺厲(雖然不是很明白,但是聽起來很厲害)的模型之前,要先講講這個詞向量 (Word Vectors)。詞向量的目的,是要讓電腦可以讀懂人類的文字,不管是英文的 「The cat is cute」 或是中文的「那隻貓好可愛」,到底要怎麼轉換成電腦可以理解、方便運算的數學形式呢?

這邊先介紹兩種經典的將文字轉換成向量的方法: one-hot encodingWord2Vec

One-hot Encoding


One-hot encoding 的概念很單純,舉個中文的例子來說明大家應該很容易就懂了。

如果我們希望電腦處理的只有這兩個句子:「我養了一隻貓」,「這隻貓很可愛」,總共需要處理的詞只有「我」、「養」、「了」、「一」、「隻」、「貓」、「這」、「很」、「可愛」。

接下來,我們可以建立一個只有這些詞的字典,這個字典共有九個詞,於是我們可以把它轉換成只有九維的向量,這個向量在代表每個詞時,只有一個維度為 1 其餘為 0,這個方法,就是 one-hot encoding 了。

我 = [1 0 0 0 0 0 0 0 0]
養 = [0 1 0 0 0 0 0 0 0]
了 = [0 0 1 0 0 0 0 0 0]
...

補充說明一下,在這系列文章講到「字」時,指的是一個個的中文字,例如「很」、「可」、「愛」,而詞指的是一個或多個中文字組成,具有完整意思的文字單位,例如「很」、「可愛」,在做詞向量時,中文大多會以「詞」為單位,而非以「字」為單位。

以英文來說就更明顯了, 「The cat is cute 」的 「The」、「cat」、「is」、「cute」就是詞 (word),「t」、「h」、「e」就是字 (character)。而英文因為詞之間有空格容易分詞,中文的話就需要如結巴或是中研院釋出的 ckiptagger 等工具來幫忙進行分詞。

介紹完 one-hot encoding 後,大家應該可以很直觀的想像,詞向量的維度會隨字典的大小增加而增加,而這個向量含有的資訊密度是相當低的。另外,每個向量兩兩之間的內積皆為 0 ,也就是說我們無法從這些詞向量中得知詞與詞之間的關係。

Word Embedding


為了改善 one-hot encoding 的種種缺點,發展出了一套稱為 Word Embedding 的學問。 Word embedding 的目的是希望把原本資訊密度低、維度高的向量,改成資訊密度高、維度少(實務上會高於 50 維,但比 one-hot encoding 的方式少得多)的向量來代表一個詞。

這個低維度的向量空間與空間中的詞向量有著一個特性,當詞與詞的意思越相近,他們在向量空間中就會越接近、兩者的夾角會越小。至於判斷詞與詞意思相近的方式,其背後的核心概念可以用一句話來說明:

"You shall know a word by the company it keeps" (J. R. Firth 1957:11)

也就是說,你可以透過一個詞的上下文來理解這個詞的意思。更具體一點來說,當兩個詞常出現在相似的上下文中,那麼這兩個詞的兩個詞向量,在向量空間中會是接近的,由下圖 word embedding 的例子應該可以更明白這個意思。

圖片出處: 李宏毅教授 Word Embedding 課程

(若想知道更多 one-hot encoding 到 word embedding 中間的各種模型與演進,推薦大家看李宏毅教授 Word Embedding 課程以及 Stanford NLP with DL word vectors 課程

Word2Vec


Word2Vec 則是學習 word embedding 的一套經典模型,這個模型在 2013 年由 Google 的 Tomas Mikolov 等人提出。這個模型值得一提的是,他不是讀完一次大量文本就得到最後的詞向量,而是迭代的讀了一次又一次,逐漸將模型中的詞向量更新,以趨近最佳結果。

Word2Vec 中又有兩種稍微不同的模型: CBOW 與 Skip-gram,簡單來說,CBOW 透過上下文 (context words) 來預測中間的詞 (center word) ,而 Skip-gram 是希望利用中間的詞去預測上下文。


圖片出處:Efficient Estimation of Word Representations in Vector Space

以 CBOW 為例,假設我們只看這個詞前後兩個詞 (window size = 2) ,從上下文計算得到中間的詞的機率。也就是對文本中所有位置的 t ,給定 w(t-2), w(t-1), w(t+1), w(t+2) 去算 w(t) 的機率為何。每次迭代不斷調整詞的向量,使得得到的機率越大越好。

Likelihood(t)
= P(w(t)|w(t-2)) * P(w(t)|w(t-1)) * P(w(t)|w(t+1)) * P(w(t)|w(t+2))

Skip-gram 則是相反,由中間詞計算得到上下文的機率,也就是給定 w(t) 去算 w(t-2), w(t-1), w(t+1), w(t+2) 的機率。

Likelihood(t)
= P(w(t-2)|w(t)) * P(w(t-1)|w(t)) * P(w(t+1)|w(t)) * P(w(t+2)|w(t))

以上大致介紹完了 CBOW 與 Skip-gram 的原理,下面我會講更多 Word2Vec 如何更新向量的數學,如果有興趣的人可以繼續往下讀。如果想要直接實作,了解以上概念其實就差不多了,現在的工具大多都幫你把數學包得好好的,可以參考 gensim-word2vec 這個工具直接進行實作。

==以下數學多,慎入==

延續剛剛提到的機率,以 Skip-gram 為例,可以把它寫成下面的 L(θ) ,θ 表示所有我們需要最佳化的變數,也就是函式的參數。將 L(θ) 取 log 後除以 T 作平均,轉換成數學上較易計算的另一個函式 J(θ)。我們的目標是使 L(θ) 越大越好,等同於使 J(θ) 越小越好。


圖片出處: Stanford NLP with DL word vectors 課程

首先,我們要計算 P(w(t+j)|w(t);θ) ,也可以寫成給予中間詞得到上下文的詞的機率 P(o|c),這個機率可以用下圖的第一個式子代表,其中 u, v 皆為詞向量。

若眼尖的人可以發現,這個式子其實就是在對詞向量內積後的值作 softmax ,將其轉換成我們要的機率分佈。


圖片出處: Stanford NLP with DL word vectors 課程

當我們得到 J(θ) 的數學式後,便可以利用 chain rule 計算其微分,以 gradient descent 的方式更新詞向量,至於 gradient descent 又是另一個主題了,有興趣的人可以直接參考 李宏毅教授 gradient descent 課程

以上,我們終於介紹完了近代 NLP 的基礎 - Word Vectors ,接下來可以開心的來看不明覺厲的各種模型了!

#NLP #ML #Nature Language Processing #machine learning #Word Vector #Word Embedding #Word2Vec #One-hot Encoding







你可能感興趣的文章

為什麼我們需要 React?可以不用嗎?

為什麼我們需要 React?可以不用嗎?

JS30 Day 20 筆記

JS30 Day 20 筆記

How to solve the perpetual loading issue in Evernote? Evernote 一直轉圈圈的解決辦法

How to solve the perpetual loading issue in Evernote? Evernote 一直轉圈圈的解決辦法






留言討論